package com.ai.dmc.index.dao.base.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

import com.ai.dmc.cache.redis.client.dao.IRedisClientDao;
import com.ai.dmc.index.common.data.PubConstant;
import com.ai.dmc.index.dao.base.IBaseDao;
import com.ai.frame.util.ConvertUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

/**
 * 用户Dao基类
 */
public class BaseDaoImpl implements IBaseDao {
	private SqlSession sqlSession;
	
	private IRedisClientDao redisClientDao;
	
	public SqlSession getSqlSession() {
		return sqlSession;
	}

	public void setSqlSession(SqlSession sqlSession) {
		this.sqlSession = sqlSession;
	}
	
	public IRedisClientDao getRedisClientDao() {
		return redisClientDao;
	}

	public void setRedisClientDao(IRedisClientDao redisClientDao) {
		this.redisClientDao = redisClientDao;
	}

	/**
	 * 根据Id获取对象
	 * 
	 * @param sqlId
	 *            脚本编号
	 * @param id
	 *            主键
	 * @return Object对象
	 */
	public Object queryForObject(String sqlId, int id) {
		Map param = new HashMap();
		param.put("id", id);
		Object data = getCacheData(sqlId,Object.class,param);
		if(data == null){
			data = getSqlSession().selectOne(sqlId, id);
			if(redisClientDao != null){
				String key = getCacheDataKey(sqlId,param);
				if(key != null && !"".equals(key)){
					String dataJson = JSON.toJSONString(data);
					redisClientDao.set(key, dataJson);
				}
			}
		}
		return data;
	}

	/**
	 * 根据Id获取对象
	 * 
	 * @param sqlId
	 *            脚本编号
	 * @param id
	 *            主键
	 * @param cls
	 *            返回的对象Class
	 * @return cls对应的类
	 */
	@SuppressWarnings("unchecked")
	public <T> T queryForObject(String sqlId, int id, Class<T> cls) {
		Map param = new HashMap();
		param.put("id", id);
		T data = getCacheData(sqlId,cls,param);
		if(data == null){
			data = (T) getSqlSession().selectOne(sqlId, id);
			if(redisClientDao != null){
				String key = getCacheDataKey(sqlId,param);
				if(key != null && !"".equals(key)){
					String dataJson = JSON.toJSONString(data);
					redisClientDao.set(key, dataJson);
				}
			}
		}
		return data;
	}

	/**
	 * 根据条件获取对象
	 * 
	 * @param sqlId
	 *            脚本编号
	 * @param params
	 *            参数
	 * @return
	 */
	public Object queryForObject(String sqlId, Map<String, String> params) {
		Object data = getCacheData(sqlId,Object.class,params);
		if(data == null){
			data = getSqlSession().selectOne(sqlId, params);
			if(redisClientDao != null){
				String key = getCacheDataKey(sqlId,params);
				if(key != null && !"".equals(key)){
					String dataJson = JSON.toJSONString(data);
					redisClientDao.set(key, dataJson);
				}
			}
		}
		return data;
	}
	//------------20160115
	public Object queryForObjectByObjectMap(String sqlId, Map<String, Object> params) {
		Object data = getCacheData(sqlId,Object.class,params);
		if(data == null){
			data = getSqlSession().selectOne(sqlId, params);
			if(redisClientDao != null){
				String key = getCacheDataKey(sqlId,params);
				if(key != null && !"".equals(key)){
					String dataJson = JSON.toJSONString(data);
					redisClientDao.set(key, dataJson);
				}
			}
		}
		return data;
    }
    
	/**
	 * 根据条件获取对象
	 * 
	 * @param sqlId
	 *            脚本编号
	 * @param params
	 *            参数
	 * @param cls
	 *            返回的对象Class
	 * @return cls对应的类
	 */
	@SuppressWarnings("unchecked")
	public <T> T queryForObject(String sqlId, Map<String, String> params,
			Class<T> cls) {
		T data = getCacheData(sqlId,cls,params);
		if(data == null){
			data = (T) getSqlSession().selectOne(sqlId, params);
			if(redisClientDao != null){
				String key = getCacheDataKey(sqlId,params);
				if(key != null && !"".equals(key)){
					String dataJson = JSON.toJSONString(data);
					redisClientDao.set(key, dataJson);
				}
			}
		}
		return data;
	}

	/**
	 * 获取数据总条数
	 * 
	 * @param sqlId
	 *            脚本编号
	 * @param params
	 *            参数
	 * @return 条数
	 */
	public int getTotalCount(String sqlId, Map<String, String> params) {
		return (Integer) getSqlSession().selectOne(sqlId, params);
	}
	//20160120
	/**
     * 获取数据总条数
     * 
     * @param sqlId
     *            脚本编号
     * @param params
     *            参数
     * @return 条数
     */
    public int getTotalCountByObjectMap(String sqlId, Map<String,Object> params) {
        return (Integer) getSqlSession().selectOne(sqlId, params);
    }
	/**
	 * 查询列表
	 * 
	 * @param sqlId
	 *            脚本编号
	 * @param params
	 *            参数
	 * @param cls
	 *            返回的对象Class
	 * @return 列表<cls对应的类>
	 */
	public <T> List<T> queryForList(String sqlId, Map<String, String> params,
			Class<T> cls) {
		List<T> data = getCacheData(sqlId,List.class,params);
		if(data == null){
			data = getSqlSession().selectList(sqlId, params);
			if(redisClientDao != null){
				String key = getCacheDataKey(sqlId,params);
				if(key != null && !"".equals(key)){
					String dataJson = JSON.toJSONString(data);
					redisClientDao.set(key, dataJson);
				}
			}
		}
		return data;
	}

	/**
	 * 查询列表
	 * 
	 * @param sqlId
	 *            脚本编号
	 * @param params
	 *            参数
	 * @return 列表
	 */
	public List<Map<String, String>> queryForList(String sqlId,
			Map<String, String> param) {
		List<Map<String, String>> data = getCacheData(sqlId,List.class,param);
		if(data == null){
			List<Map<String, Object>> list = getSqlSession().selectList(sqlId, param);
			data = ConvertUtil.convertSqlMap2JavaMap(list);
			if(redisClientDao != null){
				String key = getCacheDataKey(sqlId,param);
				if(key != null && !"".equals(key)){
					String dataJson = JSON.toJSONString(data);
					redisClientDao.set(key, dataJson);
				}
			}
		}
		return data;
	}
	
	/**
	 * 查询列表
	 * 
	 * @param sqlId
	 *            脚本编号
	 * @param params
	 *            参数
	 * @return 列表
	 */
	public List<Map<String, Object>> queryForListObj(String sqlId,
			Map<String, String> param) {
			List<Map<String, Object>> list = getSqlSession().selectList(sqlId, param);
		return list;
	}

	/**
	 * 修改数据
	 * 
	 * @param sqlId
	 *            脚本编号
	 * @param object
	 *            对象
	 * @return 修改的行�?
	 */
	public int update(String sqlId, Object object) {
		return getSqlSession().update(sqlId, object);
	}

	/**
	 * 插入数据
	 * 
	 * @param sqlId
	 *            脚本编号
	 * @param object
	 *            待插入的对象
	 * @return 插入条数
	 */
	public int insert(String sqlId, Object object) {
		return (Integer) getSqlSession().insert(sqlId, object);
	}

	/**
	 * 删除数据
	 * 
	 * @param sqlId
	 *            脚本编号
	 * @param id
	 *            主键
	 * @return 主键
	 */
	public int delete(String sqlId, int id) {
		return getSqlSession().delete(sqlId, id);
	}
	
	/**
	 * 删除数据
	 * 
	 * @param sqlId
	 *            脚本编号
	 * @param map
	 *            待删除的对象
	 * @return 主键
	 */
	public int delete(String sqlId, Map<String, String> map) {
		return getSqlSession().delete(sqlId, map);
	}
	
	/**
	 * 分页查询
	 * @param sqlId
	 * @param param
	 * @return
	 */
	public Page<?> queryForPage(String sqlId,Map<String, String> param,int curPage,int pageSize,String orderBy){

		Page<Map<String, String>> page= PageHelper.startPage(curPage,pageSize,orderBy);
		List<Map<String, Object>> list = getSqlSession().selectList(sqlId, param);
		return page;
	}
	
	//------↓----weitao----20150923------增加分页查询的方法-----↓--------
    /**
     * 查询分页列表
     * 
     * @param sqlId
     *            脚本编号
     * @param params
     *            参数
     * @return 列表
     */
    public List<Map<String, String>> queryForPageList(String sqlId,
            Map<String, String> param) {
        int pageSize = Integer.parseInt(param.get("pageSize").toString());
        int currentPage = Integer.parseInt(param.get("currentPage").toString());
        if (currentPage <= 0) {
            currentPage = 1;
        }
        
        param.remove("pageSize");
        param.remove("currentPage");
        Map<String, Object> params = new HashMap<String, Object>();
        params.putAll(param);
        params.put("startPageNum", (currentPage - 1) * pageSize+1);
        params.put("pageSize", currentPage * pageSize);
        List<Map<String, Object>> list = getSqlSession().selectList(sqlId, params);
        List<Map<String, String>> beans = ConvertUtil.convertSqlMap2JavaMap(list);
        return beans;
    }
    //---------------↑-----增加方法完毕---↑---------------------------
    //20160120
    public List<Map<String, Object>> queryForPageListByObjectMap(String sqlId,
            Map<String, Object> param) {
        int pageSize = Integer.parseInt(param.get("pageSize").toString());
        int currentPage = Integer.parseInt(param.get("currentPage").toString());
        param.remove("pageSize");
        param.remove("currentPage");
        Map<String, Object> params = new HashMap<String, Object>();
        params.putAll(param);
        params.put("startPageNum", (currentPage - 1) * pageSize+1);
        params.put("pageSize", currentPage * pageSize);
        List<Map<String, Object>> list = getSqlSession().selectList(sqlId, params);
        return list;
    }
    
    public List<Map<String, String>> queryForPageListByObjectMap2(String sqlId,
            Map<String, Object> param) {
        int pageSize = Integer.parseInt(param.get("pageSize").toString());
        int currentPage = Integer.parseInt(param.get("currentPage").toString());
        param.remove("pageSize");
        param.remove("currentPage");
        Map<String, Object> params = new HashMap<String, Object>();
        params.putAll(param);
        params.put("startPageNum", (currentPage - 1) * pageSize+1);
        params.put("pageSize", currentPage * pageSize);
        List<Map<String, String>> list = getSqlSession().selectList(sqlId, params);
        return list;
    }
   //------↓----zhull3----20150917------增加入参是Map<String,Object>的方法-----↓--------
    /**
     * 查询列表
     * 
     * @param sqlId
     *            脚本编号
     * @param params
     *            参数
     * @return 列表
     */
    public List<Map<String, Object>> queryForListByObjectMap(String sqlId,
            Map<String, Object> param) {
    	List<Map<String, Object>> data = getCacheData(sqlId,List.class,param);
		if(data == null){
			data = getSqlSession().selectList(sqlId, param);
			if(redisClientDao != null){
				String key = getCacheDataKey(sqlId,param);
				if(key != null && !"".equals(key)){
					String dataJson = JSON.toJSONString(data);
					redisClientDao.set(key, dataJson);
				}
			}
		}
		return data;
    }
    
    public List<Map<String, String>> queryForListByObjectMap2(String sqlId,
            Map<String, Object> param) {
    	List<Map<String, String>> data = getCacheData(sqlId,List.class,param);
		if(data == null){
			data = getSqlSession().selectList(sqlId, param);
			if(redisClientDao != null){
				String key = getCacheDataKey(sqlId,param);
				if(key != null && !"".equals(key)){
					String dataJson = JSON.toJSONString(data);
					redisClientDao.set(key, dataJson);
				}
			}
		}
		return data;
    }
    //---------------↑-----增加方法完毕---↑---------------------------
    
    
    private <T> T getCacheData(String sqlId,Class<T> cls,Map param){
    	String key = getCacheDataKey(sqlId,param);
    	if(key != null && !"".equals(key)){
    		String data = redisClientDao.get(key.toString());
    		T value = null;
    		if(data != null){
    			value = (T) JSON.parseObject(data, cls);
    		}
    		return value;
    	}
    	return null;
    }
    
    private String getCacheDataKey(String sqlId,Map param) {
    	String cachedSqlIdsJson = redisClientDao.get(PubConstant.SQL_IDS);
    	if(cachedSqlIdsJson != null && !"".equals(cachedSqlIdsJson)){
    		List<Map<String, Object>> sqlIdList = (List<Map<String, Object>>) JSON.parse(cachedSqlIdsJson);
    		StringBuffer key = new StringBuffer(sqlId);
        	for (Map<String, Object> map : sqlIdList) {
    			String cacheKey = String.valueOf(map.get("cacheKey"));
    			if(cacheKey.equals(sqlId)){
    				String paramKeyStr = String.valueOf(map.get("paramKey"));
    				String[] paramKeys = paramKeyStr.split(",");
    				if(paramKeys != null && paramKeys.length > 0){
    					for (String keyStr : paramKeys) {
    						String paramKey = String.valueOf(param.get(keyStr));
    						key.append(":").append(paramKey);
    					}
    				}
    				return key.toString();
    			}
    		}
    	}
		return null;
	}
}